package com.charley.icloud.filter;

import com.charley.icloud.wrapper.MyRequestWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 自定义过滤器
 *   用于拦截用户的请求路径，解决跨域问题
 * @author charley
 * @date 2024-04-16 14:35
 * */
@Component
@Slf4j
public class CrosFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        /* **
         * 设置响应头：
         * Access-Control-Allow-Origin: 解决跨域问题
         * Access-Control-Allow-Credentials：true允许客户端携带验证信息
         * Access-Control-Allow-Methods：响应访问所述资源到时允许的一种或多种方法预检请求
         * Access-Control-Max-Age：用来指定本次预检请求的有效期，单位为秒，，在此期间不用发出另一条预检请求。
         *   浏览器的同源策略，就是出于安全考虑，浏览器会限制从脚本发起的跨域HTTP请求（比如异步请求GET, POST, PUT, DELETE, OPTIONS等等），
         *   所以浏览器会向所请求的服务器发起两次请求，第一次是浏览器使用OPTIONS方法发起一个预检请求，
         *   第二次才是真正的异步请求，第一次的预检请求获知服务器是否允许该跨域请求：如果允许，才发起第二次真实的请求；如果不允许，则拦截第二次请求。
         *      例如：
         *      resp.addHeader("Access-Control-Max-Age", "0")，表示每次异步请求都发起预检请求，也就是说，发送两次请求。
         *      resp.addHeader("Access-Control-Max-Age", "1800")，表示隔30分钟才发起预检请求。也就是说，发送两次请求
         *
         * Access-Control-Allow-Headers：
         *    用于预检请求中，列出了将会在正式请求的 Access-Control-Allow-Headers 字段中出现的首部信息
         * */
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, Auth-Token");

        // 取请求体 body 数据
        String path = request.getRequestURI();

        if("/auth/api/file/upload".equals(path)){
            filterChain.doFilter(request, response);
        }else {
            MyRequestWrapper requestWrapper = new MyRequestWrapper(request);
            //String body = requestWrapper.getBody();
            filterChain.doFilter(ObjectUtils.isEmpty(requestWrapper)?request:requestWrapper, response);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }
}
